package com.m1.tzolkin.model;

import java.io.Serializable;

import com.m1.tzolkin.model.exceptions.NoAvailableSkullException;
import com.m1.tzolkin.model.exceptions.NotEnoughResourceException;

/**
 * Un mod�le de montant dans le jeu Tzolk'in.
 * Un montant Tzolk'in est un stock de ressources + une quantit� de cr�nes de cristal.
 * 
 * @pre <pre>
 *     getResources(r) >= 0
 *     getSkulls() >= 0 </pre>
 *     
 * @cons <pre>
 * $DESC$
 *     Un montant contenant la somme s et n cr�nes de cristal.
 * $ARGS$
 *     ISum<Resource> s, int n
 * $PRE$
 *     s != null
 *     n >= 0
 * $POST$
 *     getSum().equals(s)
 *     getSkulls() == n </pre>
 *
 */
public interface ITZStock extends Serializable, ObservableModel {
	
	// REQUETES
	
	/**
	 * Retourne la quantit� de r que ce stock contient.
	 * @pre <pre>
	 *     r != null </pre>
	 */
	int getResources(TZResource r);
	
	/**
	 * Retourne le nombre de cr�nes de cristal de ce montant.
	 */
	int getSkulls();
	
	/**
	 * Retourne true si ce montant contient m.
	 * @pre <pre>
	 *     m != null </pre>
	 */
	boolean contains(ITZStock m);
	
	/**
	 * Retourne true si ce montant contient m � 1 unit� de r pr�s.
	 * @pre <pre>
	 *     m != null
	 *     r != null </pre>
	 */
	boolean contains(ITZStock m, TZResource n);
	
	/**
	 * Retourne true si ce montant contient m � n cr�nes pr�s.
	 * @pre <pre>
	 *     m != null
	 *     n >= 0 </pre>
	 */
	boolean contains(ITZStock m, int n);
	
	/**
	 * Retourne true si m est �quivalent � ce montant.
	 */
	boolean equals(ITZStock m);
	
	/**
	 * Retourne la quantit� totale contenue dans ce stock.
	 */
	int getTotal();
	
	// COMMANDES
	
	/**
	 * Ajoute une unit� de l'�l�ment r.
	 * @pre <pre>
	 *     r != null </pre>
	 */
	ITZStock addResource(TZResource r);
	
	/**
	 * Retire une unit� de l'�l�ment r.
	 * @pre <pre>
	 *     r != null </pre>
	 */
	ITZStock removeResource(TZResource r);
	
	/**
	 * Ajoute i unit�s de l'�l�ment r.
	 * @pre <pre>
	 *     r != null
	 *     i > 0 </pre>
	 */
	ITZStock addResource(TZResource r, int i);
	
	/**
	 * Retire i unit�s de l'�l�ment r.
	 * @pre <pre>
	 *     r != null
	 *     i > 0 </pre>
	 */
	ITZStock removeResource(TZResource r, int i);
	
	/**
	 * Ajoute un cr�ne.
	 */
	ITZStock addSkull();
	
	/**
	 * Ajoute n unit� de r.
	 * @pre <pre>
	 *     n > 0 </pre>
	 */
	ITZStock addSkull(int n);
	
	/**
	 * Ajoute le montant m.
	 * @pre <pre>
	 *     m != null </pre>
	 */
	ITZStock add(ITZStock m);
	
	/**
	 * Retire un cr�ne.
	 * @pre <pre>
	 *     getSkulls() >= 1 </pre>
	 */
	ITZStock removeSkull() throws NoAvailableSkullException;
	
	/**
	 * Ajoute n unit� de r.
	 * @pre <pre>
	 *     getSkulls() >= n > 0 </pre>
	 */
	ITZStock removeSkull(int n) throws NoAvailableSkullException;
	
	/**
	 * Retire le montant m de ce montant.
	 * @pre <pre>
	 *     m != null
	 *     contains(m) </pre>
	 */
	ITZStock remove(ITZStock m) throws NotEnoughResourceException, NoAvailableSkullException;
	
	/**
	 * Vide ce stock.
	 */
	ITZStock clear();
	
}
